package com.demo.webapp.validator.client;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.demo.common.FormatUtils;
import com.demo.webapp.validator.ValidationResolver;
import com.demo.webapp.validator.adapter.ValidateAdapter;
import com.demo.webapp.validator.adapter.ValidateAdapter.TransWrapper;
import com.opensymphony.xwork2.inject.Container;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.validator.FieldValidator;
import com.opensymphony.xwork2.validator.Validator;

/**
 * 前端验证分解器
 * 实现由验证器到js前端验证元数据的转换
 * @author ryuu.kk
 *
 */
public class ClientMetadataValidationResolver implements ValidationResolver {

	/**
	 * struts对象容器
	 */
	//private Container container;
	
	/**
	 * 最终元数据格式
	 */
	@Inject(ValidationResolver.VALIDATOR_METADATA_FORMAT)
	private String metadataFormat;
	
	/**
	 * 适配器转换Map
	 */
	private Map<String, ValidateAdapter> adapterMap;
	
	@SuppressWarnings("rawtypes")
	@Override
	public String resolve(String field, List<Validator> fValidator) {
		String valids = "";
		String messages = "";
		if (fValidator != null) {
			for (Validator<?> validator : fValidator) {
				// 字段验证器 and 验证器验证字段与验证参数字段相同
				if (validator instanceof FieldValidator && ((FieldValidator) validator).getFieldName().equals(field)) {
					String type = validator.getValidatorType();
					ValidateAdapter validateAdapter = adapterMap.get(type);
					if (validateAdapter != null) {
						TransWrapper wrapper = validateAdapter.convert((FieldValidator) validator);
						valids += "," + wrapper.getKey() + ":" + wrapper.getValidation() ;
						messages += "," + wrapper.getKey() + ":\'" + wrapper.getMessage() + "\'";
					}
				}
			}
		}
		if (messages.length() > 0 && valids.length() > 0) {
			messages = messages.substring(1);
			valids = valids.substring(1);
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("valids", valids);
			params.put("messages", messages);
			//String.format("{%s:{%s, messages:{%s}}}", metadataTag, metadata, messages);
			return FormatUtils.format(metadataFormat, params);
		}
		
		return "";
	}

    @Inject
    public void setContainer(Container container) {
        //this.container = container;
        Set<String> prefixes = container.getInstanceNames(ValidateAdapter.class);
        Map<String, ValidateAdapter> map = new HashMap<String, ValidateAdapter>();
        for (String prefix : prefixes) {
        	map.put(prefix, container.getInstance(ValidateAdapter.class, prefix));
        }
        adapterMap = Collections.unmodifiableMap(map);
    }
    
	public void setMetadataFormat(String metadataFormat) {
		this.metadataFormat = metadataFormat;
	}
}
